package com.base.cn.platform.os.service.op.affiche;

import com.base.cn.platform.os.common.OpDataManage;
import com.base.cn.platform.os.common.constants.CacheConstants;
import com.base.cn.platform.os.common.j2cache.CustomCacheChannel;
import com.base.cn.platform.os.common.j2cache.J2CacheRegion;
import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.DateUtils;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.dao.op.affiche.OpAfficheDao;
import com.base.cn.platform.os.entity.op.affiche.OpAffiche;
import com.base.cn.platform.os.service.course.cou.CourseService;
import com.base.cn.platform.os.service.manage.subject.SysSubjectBiz;
import com.base.cn.platform.os.service.manage.user.SysUserBiz;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 消息Biz
 * @author zsw
 * @create 2018/5/12
 */
@Service
public class OpAfficheBiz extends BaseBiz<OpAffiche,OpAfficheDao> {

    @Autowired
    private SysSubjectBiz sysSubjectBiz;
    @Autowired
    private SysUserBiz sysUserBiz;
    @Autowired
    private CourseService courseService;
    @Autowired
    private CustomCacheChannel customCacheChannel;

    /**
     * 发布消息
     * @param affiche 资讯实体
     */
    public void saveUpdateAffiche(OpAffiche affiche){
        affiche.setMsgType(1);
        this.save(affiche);
        setUpdateNum();
    }

    /**
     * 删除消息
     * @param afficheIds 消息id串
     */
    public void deleteAffiche(String afficheIds){
        this.deleteWhereSql(" id in ("+ afficheIds +") ");
    }

    /**
     * 修改消息状态
     * @param afficheIds 消息id串
     * @param status 状态：0.正常 1.禁用 2.删除
     */
    public void updateArticleStatusByIds(String afficheIds, Integer status){
        if(StringUtils.isNotEmpty(afficheIds) && StringUtils.isNotEmpty(afficheIds.trim()) && ObjectUtils.isNotEmpty(status)){
            if (status == 2){
                this.deleteAffiche(afficheIds);
            } else {
                OpAffiche opArticle = new OpAffiche();
                opArticle.setStatus(status);
                this.updateByWhereSql(opArticle, " id in ("+ afficheIds +")");
            }
        }
    }

    /**
     * 查询消息列表(分页)
     * @param page 当前页数
     * @param affiche 查询条件
     * @param subjectData 是否设置专业数据
     * @param courseData 是否设置课程数据
     * @param sysUserData 是否设置创建人数据
     * @return
     */
    public PageInfo<OpAffiche> queryAfficheList(Pagination page, OpAffiche affiche,boolean subjectData,boolean courseData,boolean sysUserData){

        //查询创建人
        String createIds =null;
        if(StringUtils.isNotEmpty(affiche.getContext())){
            createIds = sysUserBiz.getUserNameIds(affiche.getContext());
        }
        String whereSql = this.getWhereSql(affiche,createIds);
        PageInfo<OpAffiche> opAfficheList = this.findPage(whereSql, page, null);
        List<OpAffiche> afficheList = opAfficheList.getList();
        setSubjectAndCourseToAfficheList(afficheList,subjectData,courseData,sysUserData);
        opAfficheList.setList(afficheList);
        return opAfficheList;
    }

    /**
     * 查询消息列表(不分页)
     * @param opAffiche   查询条件
     * @param subjectData 是否设置专业数据
     * @param courseData  是否设置课程数据
     * @param sysUserData 是否设置创建人数据
     * @return List<OpAffiche>
     */
    public List<OpAffiche> getAfficheList(OpAffiche opAffiche,boolean subjectData,boolean courseData,boolean sysUserData){
        String whereSql = getWhereSql(opAffiche,null);
        List<OpAffiche> afficheList = this.find(whereSql, null, null);
        setSubjectAndCourseToAfficheList(afficheList, subjectData, courseData, sysUserData);
        return afficheList;
    }

    /**
     * 根据id查询消息
     * @param id 消息id
     * @return
     */
    public OpAffiche findAfficheById(BigDecimal id,boolean subjectData,boolean courseData,boolean sysUserData){
        if(DataUtil.idIsNotNull(id)){
            OpAffiche affiche = this.findById(id);
            return setSubjectAndCourse(affiche,subjectData,courseData,sysUserData);
        }
        return null;
    }

    //==================================================================================================================
    /**
     * 设置添加扩展数据
     * @param affiche 消息实体
     * @param subjectData 是否设置专业科目
     * @param courseData 是否设置课程
     * @param sysUserData 是否设置创建人
     * @return
     */
    private OpAffiche setSubjectAndCourse(OpAffiche affiche,boolean subjectData,boolean courseData,boolean sysUserData){
        List<OpAffiche> afficheList = new ArrayList<>();
        afficheList.add(affiche);
        afficheList = setSubjectAndCourseToAfficheList(afficheList,subjectData,courseData,sysUserData);
        return afficheList.get(0);
    }

    /**
     * 列表设置添加扩展数据
     * @param afficheList 消息list
     * @param subjectData 是否设置专业科目
     * @param courseData 是否设置课程
     * @return
     */
    private List<OpAffiche> setSubjectAndCourseToAfficheList(List<OpAffiche> afficheList,boolean subjectData,boolean courseData,boolean sysUserData){

        if (ObjectUtils.isNotEmpty(afficheList)){
            if (courseData){
                afficheList = this.setCourseToAfficheList(afficheList,"course");
            }
            if (subjectData){
                sysSubjectBiz.setSubjectData(afficheList,subjectData);
            }
            if (sysUserData){
                sysUserBiz.setSysUserData(afficheList,sysUserData);
            }
        }
        return afficheList;
    }

    /**
     * 给消息设置 课程
     * @param str course
     * @param afficheList
     */
    public List<OpAffiche> setCourseToAfficheList(List<OpAffiche> afficheList, String str) {
        if (ObjectUtils.isNotEmpty(afficheList)) {
            String afficheCourse = "";
            for (OpAffiche affiche : afficheList) {
                if (str.equals("course") && StringUtils.isNotEmpty(affiche.getCourseIds())) {
                    afficheCourse += StringUtils.subHeadTailString(affiche.getCourseIds(), ",") + ",";
                }
            }
            String courseIds = OpDataManage.getCourseId(afficheCourse);
            Map<BigDecimal, Map<String, Object>> courseMap = null;
            if (StringUtils.isNotEmpty(courseIds)) {
                if (str.equals("course")) {
                    courseMap = courseService.findCourseToMapByIds(courseIds,false,false,false);
                }
            }
            if (ObjectUtils.isNotEmpty(courseMap)) {
                List<BigDecimal> courseIdList = new ArrayList<>(courseMap.keySet());
                for (OpAffiche affiche : afficheList) {
                    List<Map<String, Object>> courseListMap = new ArrayList<>();
                    for (BigDecimal courseId : courseIdList) {
                        if (StringUtils.isNotEmpty(affiche.getCourseIds())){
                            if (affiche.getCourseIds().contains("," + courseId.toString() + ",") && str.equals("course")) {
                                courseListMap.add(courseMap.get(courseId));
                            }
                        }
                    }
                    if (str.equals("course")) {
                        affiche.setCourseList(courseListMap);
                    }
                }
            }
        }
        return afficheList;
    }

    //==================================================================================================================

    /**
     * sql模板
     * @param affiche 查询条件
     * @return
     */
    private String getWhereSql(OpAffiche affiche,String createIds){
        String whereSql = " 1=1 ";
        if (StringUtils.isNotEmpty(affiche.getContext())) {
            whereSql += " and context like concat('%','" + affiche.getContext() + "','%')";
        }
        if (StringUtils.isNotEmpty(affiche.getStatus())){
            whereSql += " and status =" + affiche.getStatus();
        }
        if (DataUtil.idIsNotNull(affiche.getCreateUserId())) {
            whereSql += " and createUserId =" + affiche.getCreateUserId();
        }
        if (StringUtils.isNotEmpty(affiche.getCreateTime())) {
            whereSql += " and createTime >='"+ DateUtils.format(affiche.getCreateTime(), "yyyy-MM-dd HH:mm:ss") +"'";
        }
        if (StringUtils.isNotEmpty(affiche.getCourseIds())){
            whereSql += " and courseIds like concat ('%','" + affiche.getCourseIds() + "','%')";
        }
        if (StringUtils.isNotEmpty(affiche.getSubjectIds())){
            whereSql += this.getSubjectCondition(affiche.getSubjectIds());
        }
        if (StringUtils.isNotEmpty(affiche.getMsgType())){
            whereSql += " and msgType = "+ affiche.getMsgType();
        }
        if (StringUtils.isNotEmpty(affiche.getAfficheKeyWord())){
            whereSql += " and afficheKeyWord like concat('%','" + affiche.getAfficheKeyWord() + "','%')";
        }
        if (StringUtils.isNotEmpty(createIds)){
            if(StringUtils.isNotEmpty(affiche.getContext())){
                whereSql += " or createUserId in (" + createIds+")";
            }
            whereSql += " and createUserId in (" + createIds+")";
        }
        whereSql += " order by id desc";
        return whereSql;
    }

    //拼接专业科目查询条件
    private String getSubjectCondition(String subjectIds) {
        subjectIds = DataUtil.filterNotNumberStr(subjectIds);
        if (StringUtils.isNotEmpty(subjectIds)) {
            return Stream.of(subjectIds.split(","))
                    .map((v) -> "( subjectIds like '%," + v + ",%')")
                    .collect(Collectors.joining(" or ", " and ((subjectIds is null or subjectIds = '') or ", ")"));
        }
        return "";
    }

    /**
     * 设置消息缓存
     */
    public void setUpdateNum() {
        Integer num = (Integer) customCacheChannel.get(J2CacheRegion.ONE_DAY_REGION.getKey(),CacheConstants.OP_AFFICHE_UPDATE_NUM_KEY).getValue();
        if (StringUtils.isNotEmpty(num)) {
            num+=1;
        } else {
            num = 1;
        }
        customCacheChannel.set(J2CacheRegion.ONE_DAY_REGION.getKey(),CacheConstants.OP_AFFICHE_UPDATE_NUM_KEY,num);
    }
}
